#!/usr/bin/env python
#
# Copyright 2013 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Module for allowing a WiFi testing device to interact with AppEngine.

The utilities in this script are used to check for software and configuration
updates, update software, and post test results.

"""
__author__ = "Joey Freeland (joeyfreeland@gmail.com)"

import logging
import os
import re
import shutil
import urllib
import urllib2


def CheckForConfigUpdate(config, config_file):
  config_url = "http://app-website/checkin"
  config_data = urllib.urlencode(config)
  try:
    config_post = urllib2.urlopen(config_url, config_data)
    config_response = config_post.read()
    up_to_date = re.search(r"Up to date.", config_response)
    new_device = re.search(r"Device added.", config_response)
    updated = re.search(r"Updated.", config_response)
    if up_to_date:
      logging.info("The configuration version running on the device is up to "
                   "date.")
    elif new_device:
      logging.info("New device added to the administration dashboard.")
    elif updated:
      logging.info("The configuration has been updated on the server.")
    else:
      config_file = open(config_file, "w+")
      config_file.write(config_response)
      config_file.close()
      logging.info("Downloaded an updated configuration from AppEngine.")
  except:
    logging.debug("There was an error while trying to update the config.")


def CheckForSoftwareUpdate(sw_version):
  logging.info("Checking for software update.")
  version_key = {"key": "abcdefghijklmnopqrstuvwxyz"}
  version_url = "http://app-website/version"
  version_data = urllib.urlencode(version_key)
  try:
    version_check = urllib2.urlopen(version_url, version_data)
    version = version_check.read()
    if version and version != sw_version:
      logging.debug("Version outdated.  I am running version %s and the latest "
                    "is version %s", sw_version, version)
      UpdateSoftware()
    else:
      logging.info("The software version running on the device is up to date.")
  except urllib2.HTTPError as e:
    logging.debug("There was an unexpected HTTP Error while checking for a "
                  "software update: %s", e.code)
  except urllib2.URLError as e:
    logging.debug("There was an unexpected URL Error while checking for a "
                  "software update: %s", e.args)


def PostTestResults(data):
  url = "http://app-website/addtestresult"
  data = urllib.urlencode(data)
  try:
    post = urllib2.urlopen(url, data)
    results = post.read()
    post_search = re.search("TestResult written to data store.", results)
    if post_search:
      logging.info("Successfully uploaded data to AppEngine.")
  except:
    logging.debug("Encountered an error while posting network test results.")


def UpdateSoftware():
  version_key = urllib.urlencode({"key": "abcdefghijklmnopqrstuvwxyz"})
  file_url = "http://app-website/filelist"
  try:
    file_list = urllib2.urlopen(file_url, version_key).read()
  except:
    logging.debug("Encountered a problem when trying to download the latest "
                  "software packages.")
  if file_list:
    for line in file_list.split("\n"):
      if line:
        name, url, path = line.split(",")
        backup_path = "%s.bak" % path
        try:
          shutil.copyfile(path, backup_path)
        except:
          pass
        urllib.urlretrieve(url, path, data=version_key)
        if name.split(".")[1]:
          if name.split(".")[1] == "py":
            os.chmod(path, 0755)
